package com.cloud.bean;

import com.cloud.DevelopProperties;
import com.cloud.util.FileUtil;
import com.cloud.client.NextGISApiClient;
import com.cloud.ui.ControlQuickMapService;
import com.cloud.ui.PanelServiceInfo;
import com.supermap.data.*;
import com.supermap.data.conversion.DataImport;
import com.supermap.data.conversion.ImportResult;
import com.supermap.data.conversion.ImportSetting;
import com.supermap.data.conversion.ImportSettingGeoJson;
import com.supermap.desktop.controls.ui.controls.progress.SmDialogProgress;
import com.supermap.desktop.controls.utilities.MapViewUIUtilities;
import com.supermap.desktop.core.Application;
import com.supermap.desktop.core.Interface.IFormMap;
import com.supermap.desktop.core.enums.WindowType;
import com.supermap.desktop.core.progress.Interface.UpdateProgressCallable;
import com.supermap.desktop.core.utilties.DatasourceUtilities;
import com.supermap.desktop.core.utilties.FormUtilities;
import com.supermap.desktop.core.utilties.LayerUtilities;
import com.supermap.desktop.core.utilties.PrjCoordSysUtilities;

import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class ServiceInfo {
    private final int id;
    private final String name;
    private final String description;
    private final String helpURL;
    private final Status status;
    private final String url;
    private final String crs;
    private final String type;
    private final Icon icon;

    public ServiceInfo(int id, String name, String description, String helpURL, Status status, String url, String crs, String type, Icon icon) {
        this.id = id;
        this.name = name;
        this.description = description;
        this.helpURL = helpURL;
        this.status = status;
        this.url = url;
        this.crs = crs;
        this.type = type;
        this.icon = icon;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public String getDescription() {
        return description;
    }

    public String getHelpURL() {
        return helpURL;
    }

    public Status getStatus() {
        return status;
    }

    public String getUrl() {
        return url;
    }

    public String getCrs() {
        return crs;
    }

    public String getType() {
        return type;
    }

    public Icon getIcon() {
        return icon;
    }

    public PanelServiceInfo createPanel() {
        return new PanelServiceInfo(this);
    }

    public void create() {
        try {
            Datasources datasources = Application.getActiveApplication().getWorkspace().getDatasources();
            List<Datasource> connDatasource = new ArrayList<>();
            switch (type) {
                case "tms":
                    List<String> urls = NextGISApiClient.parseTmsURL(url);
                    for (String url : urls) {
                        DatasourceConnectionInfo d = new DatasourceConnectionInfo();
                        d.setEngineType(EngineType.XYZTILE);
                        d.setServer(url);
                        d.setAlias(DatasourceUtilities.getAvailableDatasourceAlias(name));
                        connDatasource.add(datasources.open(d));
                    }
                    break;
                case "wms":
                    DatasourceConnectionInfo d = new DatasourceConnectionInfo();
                    d.setEngineType(EngineType.OGC);
                    d.setDriver("wms");
                    d.setServer(url);
                    d.setAlias(DatasourceUtilities.getAvailableDatasourceAlias(name));
                    connDatasource.add(datasources.open(d));
                    break;
                case "wfs":
                    DatasourceConnectionInfo ds = new DatasourceConnectionInfo();
                    ds.setEngineType(EngineType.OGC);
                    ds.setDriver("wfs");
                    ds.setServer(url);
                    ds.setAlias(DatasourceUtilities.getAvailableDatasourceAlias(name));
                    connDatasource.add(datasources.open(ds));
                    break;
                case "geojson":
                    // 没有就下载geoJSON文件
                    File f = new File(FileUtil.getGeoJSONCacheDir() + "\\" + id + ".geojson");
                    if (f.exists()) {
                        f.delete();
                    }
                    SmDialogProgress smDialogProgress = new SmDialogProgress(DevelopProperties.getString("String_Label_Downloading") + " " + name);
                    smDialogProgress.doWork(new UpdateProgressCallable() {

                        @Override
                        public Boolean call() {
                            try {
                                NextGISApiClient.downloadGeoJSON(url,
                                        f,
                                        (progress, total) -> {
                                            if (total != -1) {
                                                updateProgress(((int) ((progress / total) * 100)), null, DevelopProperties.getString("String_Label_DownloadProgress") + String.format("%.3f", progress / 1000000) + "MB/" + String.format("%.3f", total / 1000000) + "MB");
                                            } else {
                                                updateProgress(50, null, DevelopProperties.getString("String_Label_DownloadProgress") + String.format("%.3f", progress / 1000000) + "MB");
                                            }
                                        });


                                DatasourceConnectionInfo ds = new DatasourceConnectionInfo();
                                ds.setAlias(DatasourceUtilities.getAvailableDatasourceAlias(name));
                                ds.setEngineType(EngineType.UDBX);
                                ds.setServer(":memory:");
                                Datasource datasource = datasources.create(ds);
                                PrjCoordSysUtilities.setDefaultDatasourcePrjCoordSys(datasource);
                                ImportSetting importSetting = new ImportSettingGeoJson();
                                importSetting.setSourceFilePath(f.getAbsolutePath());
                                importSetting.setTargetDatasource(datasource);
                                importSetting.setTargetDatasetName(name);
                                DataImport dataImport = new DataImport();
                                dataImport.getImportSettings().add(importSetting);
                                updateProgress(100, null, DevelopProperties.getString("String_Importing"));
                                ImportResult res = dataImport.run();
                                if (res.getSucceedSettings().length > 0) {
                                    connDatasource.add(datasource);
                                    return true;
                                } else {
                                    Application.getActiveApplication().getOutput().output(DevelopProperties.getString("String_ImportFailed"));
                                    return false;
                                }
                            } catch (IOException e) {
                                Application.getActiveApplication().getOutput().output(DevelopProperties.getString("String_NetworkRequestFailed"));
                                return false;
                            }
                        }
                    });
            }
            if (ControlQuickMapService.isAutoOpen()) {
                for (Datasource datasource : connDatasource) {
                    if (datasource.getDatasets().getCount() == 1) {
                        // 打开并全幅显示
                        IFormMap formMap = ((IFormMap) FormUtilities.fireNewWindowEvent(WindowType.MAP));
                        MapViewUIUtilities.addDatasetsToMap(formMap.getMapControl().getMap(), 0, datasource.getDatasets().get(0));
                        formMap.setTitle(datasource.getDatasets().get(0).getName());
                        Rectangle2D rectangle2D = LayerUtilities.getLayerBounds(formMap.getMapControl().getMap(), formMap.getMapControl().getMap().getLayers().get(0));
                        if (rectangle2D != null && rectangle2D.getHeight() > 0) {
                            formMap.getMapControl().getMap().setViewBounds(rectangle2D);
                        }
                        formMap.refresh();
                    }
                }
            }
        } catch (Exception e) {
            Application.getActiveApplication().getOutput().output(DevelopProperties.getString("String_ImportFailed"));
        }
    }
}
